#include "wxstreectrl.h"
#include "wxsimagelist.h"
#include "../properties/wxsimagelisteditordlg.h"
#include "../properties/wxsimagetreeeditordlg.h"

namespace {
  wxsRegisterItem<wxsTreeCtrl> Reg( _T( "TreeCtrl" ), _T( "树型框" ), wxsTWidget, _T( "标准" ), 10 );
  WXS_ST_BEGIN( wxsTreeCtrlStyles, _T( "wxTR_DEFAULT_STYLE" ) )
  WXS_ST_CATEGORY( "wxTreeCtrl" )
  WXS_ST( wxTR_EDIT_LABELS )
  WXS_ST( wxTR_NO_BUTTONS )
  WXS_ST( wxTR_HAS_BUTTONS )
  WXS_ST( wxTR_TWIST_BUTTONS )
  WXS_ST( wxTR_NO_LINES )
  WXS_ST( wxTR_FULL_ROW_HIGHLIGHT )
  WXS_ST( wxTR_LINES_AT_ROOT )
  WXS_ST( wxTR_HIDE_ROOT )
  WXS_ST( wxTR_ROW_LINES )
  WXS_ST( wxTR_HAS_VARIABLE_ROW_HEIGHT )
  WXS_ST( wxTR_SINGLE )
  WXS_ST( wxTR_MULTIPLE )
  WXS_ST( wxTR_EXTENDED )
  WXS_ST( wxTR_DEFAULT_STYLE )
  WXS_ST_DEFAULTS()
  WXS_ST_END()

  WXS_EV_BEGIN( wxsTreeCtrlEvents )
  WXS_EVI( EVT_TREE_BEGIN_DRAG, wxEVT_COMMAND_TREE_BEGIN_DRAG, wxTreeEvent, BeginDrag )
  WXS_EVI( EVT_TREE_BEGIN_RDRAG, wxEVT_COMMAND_TREE_BEGIN_RDRAG, wxTreeEvent, BeginRDrag )
  WXS_EVI( EVT_TREE_END_DRAG, wxEVT_COMMAND_TREE_END_DRAG, wxTreeEvent, EndDrag )
  WXS_EVI( EVT_TREE_BEGIN_LABEL_EDIT, wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT, wxTreeEvent, BeginLabelEdit )
  WXS_EVI( EVT_TREE_END_LABEL_EDIT, wxEVT_COMMAND_TREE_END_LABEL_EDIT, wxTreeEvent, EndLabelEdit )
  WXS_EVI( EVT_TREE_DELETE_ITEM, wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEvent, DeleteItem )
  WXS_EVI( EVT_TREE_GET_INFO, wxEVT_COMMAND_TREE_GET_INFO, wxTreeEvent, GetInfo )
  WXS_EVI( EVT_TREE_SET_INFO, wxEVT_COMMAND_TREE_SET_INFO, wxTreeEvent, SetInfo )
  WXS_EVI( EVT_TREE_ITEM_ACTIVATED, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEvent, ItemActivated )
  WXS_EVI( EVT_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxTreeEvent, ItemCollapsed )
  WXS_EVI( EVT_TREE_ITEM_COLLAPSING, wxEVT_COMMAND_TREE_ITEM_COLLAPSING, wxTreeEvent, ItemCollapsing )
  WXS_EVI( EVT_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxTreeEvent, Item_bExpanded )
  WXS_EVI( EVT_TREE_ITEM_EXPANDING, wxEVT_COMMAND_TREE_ITEM_EXPANDING, wxTreeEvent, Item_bExpanding )
  WXS_EVI( EVT_TREE_ITEM_RIGHT_CLICK, wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, wxTreeEvent, ItemRightClick )
  WXS_EVI( EVT_TREE_ITEM_MIDDLE_CLICK, wxEVT_COMMAND_TREE_ITEM_MIDDLE_CLICK, wxTreeEvent, ItemMiddleClick )
  WXS_EVI( EVT_TREE_SEL_CHANGED, wxEVT_COMMAND_TREE_SEL_CHANGED, wxTreeEvent, SelectionChanged )
  WXS_EVI( EVT_TREE_SEL_CHANGING, wxEVT_COMMAND_TREE_SEL_CHANGING, wxTreeEvent, SelectionChanging )
  WXS_EVI( EVT_TREE_KEY_DOWN, wxEVT_COMMAND_TREE_KEY_DOWN, wxTreeEvent, KeyDown )
  WXS_EVI( EVT_TREE_ITEM_GETTOOLTIP, wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP, wxTreeEvent, ItemGetToolTip )
  WXS_EVI( EVT_TREE_ITEM_MENU, wxEVT_COMMAND_TREE_ITEM_MENU, wxTreeEvent, ItemMenu )
  WXS_EV_END()
}

wxsTreeCtrl::wxsTreeCtrl( wxsItemResData *Data ):
  wxsWidget(
    Data,
    &Reg.Info,
    wxsTreeCtrlEvents,
    wxsTreeCtrlStyles ),
  m_sImageList( _T( "<none>" ) ),
  m_bExpand( false ) {
  m_arrItems.Clear();
}


void wxsTreeCtrl::OnBuildCreatingCode() {
  int i, n;
  int iRed, iGreen, iBlue;
  wxsImageList *ilist;
  int iLevel, iImg1, iImg2, iImg3, iImg4;
  wxColor colour;
  bool bBold;
  wxString sText;
  wxString arrItems[32];
  wxString sSource;
  wxString sTop;
  wxString sVarName;
  wxString sItem;
  wxString sPrevItem;
  switch( GetLanguage() ) {
    case wxsCPP: {
      AddHeader( _T( "<wx/treectrl.h>" ), GetInfo().ClassName, 0 );
      AddHeader( _T( "<wx/treectrl.h>" ), _T( "wxTreeEvent" ), 0 );
      Codef( _T( "%C(%W, %I, %P, %S, %T, %V, %N);\n" ) );
      sVarName = GetVarName();
      ilist = ( wxsImageList * ) wxsImageListEditorDlg::FindTool( this, m_sImageList );
      if( ilist != NULL ) {
        AddEventCode( wxString::Format( _T( "// Set the images for %s.\n" ), sVarName.wx_str() ) );
        sSource.Printf( _T( "%s->SetImageList(%s);\n" ), sVarName.wx_str(), m_sImageList.wx_str() );
        AddEventCode( sSource );
      }
      sTop = wxEmptyString;
      arrItems[0] = wxEmptyString;
      n = 0;
      for( i = 2; i < ( int )m_arrItems.GetCount(); i++ ) {
        sSource = m_arrItems.Item( i );
        wxsImageTreeEditorDlg::ParseTreeItem( sSource, iLevel, colour, bBold, iImg1, iImg2, iImg3, iImg4, sText );
        n += 1;
        sItem.Printf( _T( "_Item%d" ), n );
        sItem = sVarName + sItem;
        arrItems[iLevel] = sItem;
        if( i == 3 ) {
          sTop = sItem;
        }
        if( iLevel <= 0 ) {
          sPrevItem = wxEmptyString;
        } else
        { sPrevItem = arrItems[iLevel - 1]; }
        if( iLevel <= 0 ) {
          Codef( _T( "wxTreeItemId %s = %s->AddRoot(%n);\n" ), sItem.wx_str(), sVarName.wx_str(), sText.wx_str() );
        } else
        { Codef( _T( "wxTreeItemId %s = %s->AppendItem(%s, %n);\n" ), sItem.wx_str(), sVarName.wx_str(), sPrevItem.wx_str(), sText.wx_str() ); }
        iRed = colour.Red();
        iGreen = colour.Green();
        iBlue = colour.Blue();
        if( ( colour.IsOk() ) && ( ( iRed + iGreen + iBlue ) != 0 ) ) {
          sSource.Printf( _T( "%d,%d,%d" ), iRed, iGreen, iBlue );
          Codef( _T( "%ASetItemTextColour(%s, wxColour(%s));\n" ), sItem.wx_str(), sSource.wx_str() );
        }
        if( bBold ) {
          Codef( _T( "%ASetItemBold(%s, true);\n" ), sItem.wx_str() );
        }
        if( ilist != NULL ) {
          if( iImg1 >= 0 ) {
            sSource.Printf( _T( "%s->SetItemImage(%s, %d, wxTreeItemIcon_Normal);\n" ), sVarName.wx_str(), sItem.wx_str(), iImg1 );
            AddEventCode( sSource );
          }
          if( iImg2 >= 0 ) {
            sSource.Printf( _T( "%s->SetItemImage(%s, %d, wxTreeItemIcon_Selected);\n" ), sVarName.wx_str(), sItem.wx_str(), iImg2 );
            AddEventCode( sSource );
          }
          if( iImg3 >= 0 ) {
            sSource.Printf( _T( "%s->SetItemImage(%s, %d, wxTreeItemIcon_Expanded);\n" ), sVarName.wx_str(), sItem.wx_str(), iImg3 );
            AddEventCode( sSource );
          }
          if( iImg4 >= 0 ) {
            sSource.Printf( _T( "%s->SetItemImage(%s, %d, wxTreeItemIcon_SelectedExpanded);\n" ), sVarName.wx_str(), sItem.wx_str(), iImg4 );
            AddEventCode( sSource );
          }
        }
      }
      if( m_bExpand ) {
        Codef( _T( "%AExpandAll();\n" ) );
      }
      if( sTop.Length() > 0 ) {
        Codef( _T( "%AScrollTo(%s);\n" ), sTop.wx_str() );
      }
      BuildSetupWindowCode();
      return;
    }
    case wxsUnknownLanguage:
    default: {
      wxsCodeMarks::Unknown( _T( "wxsTreeCtrl::OnBuildCreatingCode" ), GetLanguage() );
    }
  }
}

wxObject *wxsTreeCtrl::OnBuildPreview( wxWindow *Parent, long Flags ) {
  int i, n;
  wxsImageList *ilist;
  int iLevel, iImg1, iImg2, iImg3, iImg4;
  wxColor colour;
  bool bBold;
  wxString sText;
  wxTreeItemId idItems[32];
  wxString sSource;
  wxTreeItemId item;
  wxTreeItemId top;
  wxTreeCtrl *preview = new wxTreeCtrl( Parent, GetId(), Pos( Parent ), Size( Parent ), Style() );
  preview->DeleteAllItems();
  m_imageList.RemoveAll();
  ilist = ( wxsImageList * ) wxsImageListEditorDlg::FindTool( this, m_sImageList );
  if( ilist != NULL ) {
    ilist->GetImageList( m_imageList );
  }
  preview->SetImageList( &m_imageList );
  n = m_arrItems.GetCount();
  for( i = 2; i < n; i++ ) {
    sSource = m_arrItems.Item( i );
    wxsImageTreeEditorDlg::ParseTreeItem( sSource, iLevel, colour, bBold, iImg1, iImg2, iImg3, iImg4, sText );
    if( iLevel == 0 ) {
      item = preview->AddRoot( sText );
    } else
    { item = preview->AppendItem( idItems[iLevel - 1], sText ); }
    idItems[iLevel] = item;
    if( i == 3 ) {
      top = item;
    }
    if( colour.IsOk() ) {
      preview->SetItemTextColour( item, colour );
    }
    preview->SetItemBold( item, bBold );
    preview->SetItemImage( item, iImg1, wxTreeItemIcon_Normal );
    preview->SetItemImage( item, iImg2, wxTreeItemIcon_Selected );
    preview->SetItemImage( item, iImg3, wxTreeItemIcon_Expanded );
    preview->SetItemImage( item, iImg4, wxTreeItemIcon_SelectedExpanded );
  };
  if( m_bExpand ) {
    preview->ExpandAll();
  }
  if( top.IsOk() ) {
    preview->ScrollTo( top );
  }
  top.Unset();
  return SetupWindow( preview, Flags );
}


void wxsTreeCtrl::OnEnumWidgetProperties( M_Code_unused long Flags ) {
  static wxString     sImageNames[128];
  static const wxChar *pImageNames[128];
  int                 i, n;
  wxString            ss, tt;
  wxArrayString       aa;
  FindAllImageLists( aa );
  n = aa.GetCount();
  if( n > 127 ) {
    n = 127;
  }
  for( i = 0; i < n; i++ ) {
    ss = aa.Item( i );
    sImageNames[i] = ss;
    pImageNames[i] = ( const wxChar * ) sImageNames[i];
  }
  pImageNames[n] = NULL;
  WXS_EDITENUM( wxsTreeCtrl, m_sImageList, _T( "Image List" ), _T( "image_list" ), pImageNames, _T( "<none>" ) )
  UpdateTreeItemList();
  WXS_IMAGETREE( wxsTreeCtrl, m_arrItems, _T( "Tree Items" ), wxT( "tree_items" ) );
  WXS_ARRAYSTRING( wxsTreeCtrl, m_arrItems, _T( "Items as Text" ), wxT( "items_text" ), _T( "item2" ) );
  WXS_BOOL( wxsTreeCtrl, m_bExpand, _T( "Expand All" ), _T( "expand_all" ), false );
}


void wxsTreeCtrl::FindAllImageLists( wxArrayString &aNames ) {
  int             i, n;
  wxsItemResData  *res;
  wxsTool         *tool;
  wxString        ss, tt;
  aNames.Clear();
  aNames.Add( _T( "<none>" ) );
  res = GetResourceData();
  n   = res->GetToolsCount();
  for( i = 0; i < n; i++ ) {
    tool = res->GetTool( i );
    ss   = tool->GetUserClass();
    if( ( ss == wxT( "wxImageList" ) ) && ( n < 127 ) ) {
      ss = tool->GetVarName();
      aNames.Add( ss );
    }
  }
}


void wxsTreeCtrl::UpdateTreeItemList() {
  int              i, n;
  wxString         ss, tt;
  wxArrayString    aa;
  aa.Clear();
  ss = GetVarName();
  aa.Add( ss );
  ss = m_sImageList;
  aa.Add( ss );
  n = m_arrItems.GetCount();
  for( i = 2; i < n; i++ ) {
    ss = m_arrItems.Item( i );
    aa.Add( ss );
  }
  m_arrItems.Clear();
  n = aa.GetCount();
  for( i = 0; i < n; i++ ) {
    ss = aa.Item( i );
    m_arrItems.Add( ss );
  }
  wxsImageListEditorDlg::FindTool( this, m_sImageList );
}
